package com.demo.example.goods.service;

import com.demo.example.dto.OrderDTO;
import com.demo.example.goods.dao.GoodsRepository;
import com.demo.example.goods.domain.Goods;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by azhai on 2017/4/1.
 */
@Service
public class GoodsService {

    private static final Logger LOG = LoggerFactory.getLogger(GoodsService.class);

    @Autowired
    private JmsTemplate jmsTemplate;
    @Autowired
    private GoodsRepository goodsRepository;

    @Transactional
    @JmsListener(destination = "order:new", containerFactory = "msgFactory")
    public void handleGoodsLock(OrderDTO msg) {
        LOG.info("Get new order for goods lock:{}", msg);
        int lockCount = goodsRepository.lockGoods(msg.getCustomerId(), msg.getGoodsNum());
        if (lockCount == 0) {
            msg.setStatus("GOODS_LOCK_FAIL");
            jmsTemplate.convertAndSend("order:fail", msg);
        } else {
            msg.setStatus("GOODS_LOCKED");
            jmsTemplate.convertAndSend("order:locked", msg);
        }
    }

    @Transactional
    @JmsListener(destination = "order:goods_move", containerFactory = "msgFactory")
    public void handleGoodsMove(OrderDTO msg) {
        LOG.info("Get new order for goods move:{}", msg);
        int moveCount = goodsRepository.moveGoods(msg.getCustomerId(), msg.getGoodsNum());
        if (moveCount == 0) {
            LOG.info("Goods already transferred.");
        }
        msg.setStatus("GOODS_MOVED");
        jmsTemplate.convertAndSend("order:finish", msg);
    }

    /**
     * 触发 error_goods 的情况：
     *  1. 扣费失败，需要解锁商品
     *  2. 订单超时，如果存在锁商品就解锁，如果已经交商品就撤回
     *  这时候，都已经在OrderDTO里设置了失败的原因，所以这里就不再设置原因。
     * @param msg
     */
    @Transactional
    @JmsListener(destination = "order:goods_error", containerFactory = "msgFactory")
    public void handleError(OrderDTO msg) {
        LOG.info("Get order error for goods unlock:{}", msg);
        int count = goodsRepository.unMoveGoods(msg.getCustomerId(), msg.getGoodsNum()); // 撤销商品的转移
        if (count == 0) {
            LOG.info("Goods already unlocked:", msg);
        }
        count = goodsRepository.unLockGoods(msg.getCustomerId(), msg.getGoodsNum()); // 撤销锁商品
        if (count == 0) {
            LOG.info("Goods already unmoved, or not moved:", msg);
        }
        jmsTemplate.convertAndSend("order:fail", msg);
    }

    @Transactional
    public Goods lockGoods(OrderDTO orderDTO) {
        Goods goods = goodsRepository.findOneByGoodsNum(orderDTO.getGoodsNum());
        goods.setLockUser(orderDTO.getCustomerId());
        goods = goodsRepository.save(goods);
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            LOG.error(e.getMessage());
        }
        return goods;
    }

    @Transactional
    public int lockGoods2(OrderDTO orderDTO) {
        int updateCount = goodsRepository.lockGoods(orderDTO.getCustomerId(), orderDTO.getGoodsNum());
        LOG.info("Updated goods count:{}", updateCount);
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            LOG.error(e.getMessage());
        }
        return updateCount;
    }

    @Transactional
    public int unLockGoods(OrderDTO orderDTO) {
        int updateCount = goodsRepository.unLockGoods(orderDTO.getCustomerId(), orderDTO.getGoodsNum());
        LOG.info("Updated goods count:{}", updateCount);
        return updateCount;
    }
}
